#include "data_type.h"

//*******************************************************************
//	data_buffer functions
//*******************************************************************
void * data_buffer_init_1k(struct data_buffer *db);
void * data_buffer_init_16k(struct data_buffer *db);
bool data_buffer_reset_1k(struct data_buffer *db);
bool data_buffer_reset_16k(struct data_buffer *db);
void data_buffer_destroy(struct data_buffer *db);
bool data_buffer_equal(struct data_buffer *db1,struct \
		data_buffer *db2);
void  data_buffer_duplicate(struct data_buffer *origin,struct data_buffer*);
void * data_buffer_resize(struct data_buffer *db);
void * add_data(struct data_buffer *db,const char *dataPtr,long dataSize);


//************************************************************
//	初始化data_buffer数据结构
//************************************************************
//	define struct data_buffer db;
//	do not use struct data_buffer *db;
//***********************************************************

void * data_buffer_init_1k(struct data_buffer *db){
	db->contentPtr=malloc(DATA_BUFFER_SIZE_1K+1);
	if(db->contentPtr == NULL)
		return NULL;
	db->dataSize=0;
	db->buffSize=DATA_BUFFER_SIZE_1K;
	(db->contentPtr)[0]='\0';
	return db->contentPtr;
}

//************************************************************
//	初始化data_buffer数据结构
//************************************************************
//	define struct data_buffer db;
//	do not use struct data_buffer *db;
//***********************************************************

void * data_buffer_init_16k(struct data_buffer *db){
	db->contentPtr=malloc(DATA_BUFFER_SIZE+1);
	if(db->contentPtr == NULL)
		return NULL;
	db->dataSize=0;
	db->buffSize=DATA_BUFFER_SIZE;
	(db->contentPtr)[0]='\0';
	return db->contentPtr;
}

//*******************************************************
//	reset contentPtr dataSize=0
//	for later use
//*******************************************************
bool data_buffer_reset_1k(struct data_buffer *db){
	//free(db->contentPtr);
	data_buffer_destroy(db);
	if(data_buffer_init_1k(db)!=NULL){
		return true;
	}else{
		return false;
	}
}

//*******************************************************
//	reset contentPtr dataSize=0
//	for later use
//*******************************************************
bool data_buffer_reset_16k(struct data_buffer *db){
	data_buffer_destroy(db);
	if(data_buffer_init_16k(db)!=NULL)
		return true;
	else
		return false;
}

//*******************************************************
//	free data_buffer->contentPtr
//	set dataSize=0
//*******************************************************
void data_buffer_destroy(struct data_buffer *db){
	if(db->contentPtr!=NULL){
		free(db->contentPtr);
	}
	db->dataSize=0;
	db->buffSize=0;
	db->contentPtr=NULL;
}

//********************************************************
//	copy data buffer src------>dst
//********************************************************
void data_buffer_duplicate(struct data_buffer *dst,\
		struct data_buffer *src){
	dst->dataSize=src->dataSize;
	dst->buffSize=src->buffSize;
	if(dst->contentPtr != NULL )
		free(dst->contentPtr);
	dst->contentPtr=malloc(src->buffSize+1);
	(dst->contentPtr)[0]='\0';
	if( src->dataSize && src->contentPtr!=NULL ){
		char *p=mempcpy(dst->contentPtr,src->contentPtr,\
			dst->dataSize);
		*p='\0';
	}
	return ;
}

//********************************************************
//	只能比较ascii文本	
//********************************************************
bool data_buffer_equal(struct data_buffer *db1,struct \
		data_buffer *db2){
	if(db1->contentPtr==NULL||db2->contentPtr==NULL)
		return false;
	if((db1->dataSize == db2->dataSize) && (db1->buffSize == \
			db2->buffSize)){
		if(!strcmp(db1->contentPtr,db2->contentPtr))
			return true;
	}
	return false;
}

//********************************************************
//	扩展缓存区大小
//********************************************************
void * data_buffer_resize(struct data_buffer *db){
	char *tmp=malloc( (db->buffSize)*2+1);
	if (tmp == NULL)
		return NULL;
	memset(tmp,0,db->buffSize*2+1);
	char *p=mempcpy(tmp,db->contentPtr,db->dataSize);
	*p='\0';
	free(db->contentPtr);
	db->contentPtr=tmp;
	db->dataSize=db->dataSize;
	db->buffSize=(db->buffSize)*2;
	return db;
}

//********************************************************
//	向缓存区写入数据 数据尾加'\0'
//********************************************************
void * add_data(struct data_buffer *db,const char *dataPtr,\
		long dataSize){
	if(db->contentPtr!=NULL){
		while( (db->buffSize)< dataSize+(db->dataSize) ){
			db=data_buffer_resize(db);	
			if(db == NULL)
				return NULL;
		}
		char *p=mempcpy( (db->contentPtr)+(db->dataSize),dataPtr,dataSize );
		*p='\0';
		db->dataSize+=dataSize;
		return db;
	}
	else
		return NULL;
}

//*******************************************************************
//	int queue functions
//*******************************************************************
struct int_queue_node * int_queue_init(void);
void* in_queue(struct int_queue_node*,int node_value);
bool out_queue(struct int_queue_node*,int* ret_node_value);
bool queue_empty(struct int_queue_node*);
bool value_in_queue(struct int_queue_node*,int value);
void destroy_int_queue(struct int_queue_node*);
int int_queue_count(struct int_queue_node*);
//	struct int_queue_node{
//		int node_value;	
//		struct int_queue_node* next;
//	}

struct int_queue_node * int_queue_init(void){
	struct int_queue_node*  tmp=malloc(sizeof(struct int_queue_node));
	if(tmp!=NULL)
		tmp->next=NULL;
	return tmp;
}

void* in_queue(struct int_queue_node* head,int node_value){
	struct int_queue_node* tmp=malloc(sizeof(struct int_queue_node));
	if(tmp==NULL){return NULL;}
	tmp->next=NULL;
	tmp->node_value=node_value;
	struct int_queue_node *ret=head;
	while(head->next!=NULL){
		head=head->next;
	}
	head->next=tmp;
	return ret;
}

bool out_queue(struct int_queue_node *head,int* ret_node_value){
	if( queue_empty(head) ){return false;}
	struct int_queue_node *data_node=head->next;
	*ret_node_value=data_node->node_value;
	head->next=data_node->next;
	free(data_node);
	return true;
}

bool queue_empty(struct int_queue_node* head){
	if( head->next == NULL )
	       return true;
	else
		return false;	
}

bool value_in_queue(struct int_queue_node* head,int value){
	while(head->next!=NULL){
		head=head->next;
		if(head->node_value == value)
			return true;
	}
	return false;
}

int int_queue_count(struct int_queue_node* head){
	int node_number=0;
	while(head->next!=NULL){
		node_number++;
		head=head->next;
	}
	return node_number;
}
void destroy_int_queue(struct int_queue_node *head){
	if(head==NULL){return;}
	struct int_queue_node *tmp;
	while(head!=NULL){
		tmp=head->next;
		free(head);
		head=tmp;
	}
	return;
}

//***********************************************************************
//	order info queue
//***********************************************************************
//	return	NULL when failed
//	return	new node ptr when success

//	struct order_info_node{
//		struct order_info 	order;
//		struct order_info_node* next;
//	}



//	调度指令队列初始化
struct order_info_node* orders_init(void){
	struct order_info_node *head=malloc(sizeof(struct order_info_node));
	if(head!=NULL)
		head->next=NULL;//set head next ptr to NULL
	return head;
}

//	调度指令队列销毁
void orders_destroy(struct order_info_node *head){
	if(head==NULL)return;
	struct order_info_node *current=head;
	struct order_info_node *next;
	while(current!=NULL){
		next=current->next;
		free(current);
		current=next;
		//next=current->next;
	}
	return ;
}

//	调度指令空？
bool orders_empty(struct order_info_node* head){
	if(head->next==NULL)return true;
	else
		return false;
}

//	新增调度指令
bool add_orders(struct order_info_node *head,struct order_info\
		*info){
	while(head->next!=NULL){
		head=head->next;
	}
	struct order_info_node *new_node=malloc(sizeof(struct order_info_node));
	if(new_node==NULL)return false;
	memcpy(&(new_node->order),info,sizeof(struct order_info));
	new_node->next=NULL;
	head->next=new_node;
	return true;
}

//	调度指令出列
bool out_orders(struct order_info_node *head,struct order_info\
		*info){
	if(orders_empty(head))return false;
	struct order_info_node *apple=head->next;
	memcpy(info,&(apple->order),sizeof(struct order_info));
	head->next=head->next->next;
	free(apple);
	return true;
}

//	调度指令队列复制
//	调用程序需要初始化 dst 和 src
void duplicate_orders(struct order_info_node *dst,struct order_info_node\
		*src){
	struct order_info_node *new_node=NULL;
	struct order_info *dst_info;
	struct order_info *src_info;
	while(src->next!=NULL){
		new_node=malloc(sizeof(struct order_info_node));
		src_info=&(src->next->order);
		dst_info=&(new_node->order);
		memcpy(dst_info,src_info,sizeof(struct order_info));
		new_node->next=NULL;
		dst->next=new_node;
		dst=dst->next;
		src=src->next;
	}
	return;
}


//******************************************************************************
//	order_page functions
//******************************************************************************
/*
struct order_page{
        long tb_order_id;
        int  order_year;
        char order_code[30];
        char station_id[4];
        char send_date[20];
        char recv_date[20];
        //...
        struct order_info_node* orders;
};
*/


//***************************************************************************
//	新建调单，一个调单包含多条调度指令
//***************************************************************************
bool order_page_init(struct order_page *target){
	if( target->orders=orders_init() )// !=NULL
		return true;
	return false;				//==NULL
}

//***************************************************************************
//	销毁调单
//***************************************************************************
void order_page_destroy(struct order_page *op){
	if(op==NULL)return;
	orders_destroy(op->orders);
	op->orders=NULL;
	return;
}

//***************************************************************************
//	复制 order_page
//***************************************************************************

bool duplicate_order_page(struct order_page *dst,struct order_page *src){
	struct order_info_node *tmp1;
	struct order_info_node *tmp2;
	memcpy(dst,src,sizeof(struct order_page));
	if( (dst->orders=orders_init()) == NULL )return false;
	tmp1=dst->orders;
	tmp2=src->orders;
	duplicate_orders(tmp1,tmp2);
	return true;
}

//******************************************************************************
//	order_page_queue
//******************************************************************************

struct order_page_node* order_pages_init(void){
	struct order_page_node *ret=malloc(sizeof(struct order_page_node));
	if(ret!=NULL)
		ret->next=NULL;
	return ret;
}

void order_pages_destroy(struct order_page_node *head){
	struct order_page_node *tmp=head;
	while(head!=NULL){
		tmp=head->next;
		free(head);
		head=tmp;
	}
}

bool  order_pages_empty(struct order_page_node *head){
	if(head->next==NULL)
		return true;
	return false;
}

//*************************************************************************
//	调度零详细信息入队
//*************************************************************************
bool add_order_pages(struct order_page_node *head,struct order_page *op){
	while(head->next!=NULL){
		head=head->next;
	}
	struct order_page_node *new_op=malloc(sizeof(struct order_page_node));
	if(new_op==NULL){return false;}
	head->next=new_op;
	duplicate_order_page(&(new_op->order_page),op);
	new_op->next=NULL;
	return true;
}

//*************************************************************************
//	调度零详细信息出队
//*************************************************************************
bool out_order_pages(struct order_page_node *head,struct order_page *target){
	if(order_pages_empty(head))return false;
	struct order_page_node *apple_op=head->next;
	//	apple_op---->target
	duplicate_order_page(target,&(apple_op->order_page));
	head->next=head->next->next;
	order_page_destroy(&(apple_op->order_page));
	free(apple_op);
	return true;
}

//***********************************************************************
//
//***********************************************************************
struct ws_data_node* ws_data_queue_init(void){
	struct ws_data_node *ret=malloc(sizeof(struct ws_data_node));
	if(ret==NULL)return NULL;
	ret->next=NULL;
	return ret;
}

void ws_data_queue_destroy(struct ws_data_node *head){
	if(head==NULL){return;}
	struct ws_data_node *tmp;
	while(head!=NULL){
		tmp=head->next;
		free(head);
		head=tmp;
	}
	return;
}

bool ws_data_empty(struct ws_data_node* head){
	if(head->next==NULL)
		return true;
	return false;
}

bool add_ws_data(struct ws_data_node *head,struct data_buffer* node){
	while(head->next!=NULL){
		head=head->next;
	}
	struct ws_data_node *new_node=malloc(sizeof(struct ws_data_node));
	if(new_node==NULL)return false;
	head->next=new_node;
	new_node->next=NULL;
	data_buffer_init_16k(&new_node->ws_data);
	data_buffer_duplicate(&(new_node->ws_data),node);
	return true;
}

bool out_ws_data(struct ws_data_node* head,struct data_buffer* target){
	if(ws_data_empty(head))return false;
	struct ws_data_node *apple=head->next;
	data_buffer_duplicate(target,&(apple->ws_data));
	data_buffer_destroy(&(apple->ws_data));
	head->next=apple->next;
	free(apple);
	return true;
}

void print_all_ws_data(struct ws_data_node *head){
	int count=1;
	if(ws_data_empty(head)){printf("Empty\n");}
	while(head->next!=NULL){
		head=head->next;
		printf("Node:%4zu\n",count++);
		printf("Content:%.*s\n",(head->ws_data).dataSize,(head->ws_data).contentPtr);
	}
	return;
}


